/*
 * @Author: Wangjun
 * @Date: 2023-04-14 10:54:23
 * @LastEditTime: 2025-11-11 17:59:44
 * @LastEditors: wangjun haodreams@163.com
 * @Description:
 * @FilePath: \libs\easy\map.go
 * hnxr
 */
package easy

import "sort"

type Key interface {
	int64 | int32 | int16 | int8 | uint64 | uint32 | uint16 | uint8 | int | uint | string
}

//数组自动生成map结构
func GroupBy[K Key, V any](vs []*V, f func(*V) K) (m map[K][]*V) {
	type ls struct {
		list []*V
	}
	mp := map[K]*ls{}
	m = make(map[K][]*V)

	for _, v := range vs {
		k := f(v)
		p := mp[k]
		if p == nil {
			p = new(ls)
			mp[k] = p
		}
		p.list = append(p.list, v)
	}
	
	for k,v:=range mp{
		m[k] = v.list
	}
	return
}

//map 转排序的数组
func Map2SortList[K Key, V any](m map[K]V) []V {
	type kv struct {
		k K
		v V
	}
	kvs := make([]*kv, len(m))

	i := 0
	for k, v := range m {
		p := new(kv)
		p.k = k
		p.v = v
		kvs[i] = p
		i++
	}
	sort.Slice(kvs, func(i, j int) bool {
		return kvs[i].k < kvs[j].k
	})
	list := make([]V, len(kvs))
	for i, v := range kvs {
		list[i] = v.v
	}
	return list
}

//作用：将列表转换为另一个列表 参考js的map
func Map[T any, K any](list []T, f func(T) K) (newList []K) {
	if list == nil {
		return
	}
	newList = make([]K, len(list))
	for i, v := range list {
		newList[i] = f(v)
	}
	return
}

/**
 * @description: 数组转为map
 * @return {*}
 */
func ToMap[T comparable](list []T) (m map[T]int) {
	m = map[T]int{}
	for i, a := range list {
		m[a] = i
	}
	return
}

//列表转为map
func ListToMap[K comparable, T any](list []*T, fid func(*T) K) (m map[K]*T) {
	m = make(map[K]*T)
	for _, e := range list {
		m[fid(e)] = e
	}
	return m
}

/**
 * @description: 复制一个map
 * @return {*}
 */
func CopyMap[K comparable, V any](mp map[K]V) (m map[K]V) {
	m = make(map[K]V)
	for k, v := range mp {
		m[k] = v
	}
	return
}

func MapKeys[K comparable, V any](m map[K]V) []K {
	ks := make([]K, len(m))
	i := 0
	for k := range m {
		ks[i] = k
		i++
	}
	return ks
}

func Map2List[K comparable, V any](m map[K]V) []V {
	ks := make([]V, len(m))
	i := 0
	for _, v := range m {
		ks[i] = v
		i++
	}
	return ks
}
